package com.zgy.job;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.csv.CsvReader;
import cn.hutool.core.text.csv.CsvRow;
import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.json.JSONUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;

/**
 * @author zhengguiyang start
 * @create 2025-03-20 20:40
 */

public class Job implements Runnable{
    private String ModuleExcel;
    private String InsertExcel;
    private int CommitRow;
    private List<SheetConfig> sheetConfigList;

    public int getCommitRow() {
        return CommitRow;
    }

    public void setCommitRow(int commitRow) {
        CommitRow = commitRow;
    }

    public static class SheetConfig{

        private String SheetName;
        private String DataFileName;
        private String DataFileFieldSeparator;
        private String DataFileCharSet;
        private List<Integer> DataFileNumberTypeCols;
        private int ExcelStartRowNum;
        private int ExcelStartColNum;

        public SheetConfig() {
        }

        public List<Integer> getDataFileNumberTypeCols() {
            return DataFileNumberTypeCols;
        }

        public void setDataFileNumberTypeCols(List<Integer> dataFileNumberTypeCols) {
            DataFileNumberTypeCols = dataFileNumberTypeCols;
        }

        public SheetConfig(String sheetName, String dataFileName, String dataFileFieldSeparator, String dataFileCharSet, int excelStartRowNum, int excelStartColNum, List<Integer> dataFileNumberTypeCols) {
            SheetName = sheetName;
            DataFileName = dataFileName;
            DataFileFieldSeparator = dataFileFieldSeparator;
            DataFileCharSet = dataFileCharSet;
            DataFileNumberTypeCols = dataFileNumberTypeCols;
            ExcelStartRowNum = excelStartRowNum;
            ExcelStartColNum = excelStartColNum;

        }

        public String getSheetName() {
            return SheetName;
        }

        public void setSheetName(String sheetName) {
            SheetName = sheetName;
        }

        public String getDataFileName() {
            return DataFileName;
        }

        public void setDataFileName(String dataFileName) {
            DataFileName = dataFileName;
        }

        public char getDataFileFieldSeparator() {
            return DataFileFieldSeparator.toCharArray()[0];
        }

        public void setDataFileFieldSeparator(String dataFileFieldSeparator) {
            DataFileFieldSeparator = dataFileFieldSeparator;
        }

        public String getDataFileCharSet() {
            return DataFileCharSet;
        }

        public void setDataFileCharSet(String dataFileCharSet) {
            DataFileCharSet = dataFileCharSet;
        }
        public int getExcelStartRowNum() {
            return ExcelStartRowNum;
        }

        public void setExcelStartRowNum(int excelStartRowNum) {
            ExcelStartRowNum = excelStartRowNum;
        }

        public int getExcelStartColNum() {
            return ExcelStartColNum;
        }

        public void setExcelStartColNum(int excelStartColNum) {
            ExcelStartColNum = excelStartColNum;
        }
    }

    public Job(){
    }

    public Job(String moduleExcel, String insertExcel) {
        ModuleExcel = moduleExcel;
        InsertExcel = insertExcel;
    }

    public List<SheetConfig> getSheetConfigList() {
        return sheetConfigList;
    }

    public void setSheetConfigList(List<SheetConfig> sheetConfigList) {
        this.sheetConfigList = sheetConfigList;
    }


    public String getModuleExcel() {
        return ModuleExcel;
    }

    public void setModuleExcel(String moduleExcel) {
        ModuleExcel = moduleExcel;
    }

    public String getInsertExcel() {
        return InsertExcel;
    }

    public void setInsertExcel(String insertExcel) {
        InsertExcel = insertExcel;
    }

    @Override
    public String toString() {
        return JSONUtil.toJsonPrettyStr(this);
    }

    public void writeToExcel() {
        setInsertExcelStartRowAndCol();
        CsvReader csvReader = CsvUtil.getReader();
        BufferedInputStream inputStream=null;
        SXSSFWorkbook sxssfWorkbook=null;
        BufferedOutputStream outputStream = FileUtil.getOutputStream(getInsertExcel());
        try {
            if (Objects.nonNull(getModuleExcel())) {
                inputStream = FileUtil.getInputStream(getModuleExcel());
                sxssfWorkbook = new SXSSFWorkbook(new XSSFWorkbook(inputStream), getCommitRow());
                for (SheetConfig sheetConfig : getSheetConfigList()) {
                    SXSSFSheet sheet = sxssfWorkbook.getSheet(sheetConfig.getSheetName());
                    sheetWrite(csvReader, sheetConfig, sheet);
                }
                sxssfWorkbook.write(outputStream);
                sxssfWorkbook.close();
                outputStream.close();
            }

            if (Objects.isNull(getModuleExcel())){
                sxssfWorkbook = new SXSSFWorkbook(new XSSFWorkbook(), getCommitRow());
                for (SheetConfig sheetConfig : getSheetConfigList()) {
                    SXSSFSheet sheet = sxssfWorkbook.createSheet(sheetConfig.getSheetName());
                    sheetWrite(csvReader, sheetConfig, sheet);
                }
                sxssfWorkbook.write(outputStream);
                sxssfWorkbook.close();
                outputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void setInsertExcelStartRowAndCol() {
        for (SheetConfig sheetConfig : getSheetConfigList()) {
            for (int i = 0; i < sheetConfig.getDataFileNumberTypeCols().size(); i++) {
                sheetConfig.getDataFileNumberTypeCols().set(i,sheetConfig.getDataFileNumberTypeCols().get(i)+sheetConfig.getExcelStartColNum());
            }
        }
    }

    private void sheetWrite(CsvReader csvReader, SheetConfig sheetConfig, SXSSFSheet sheet) {
        csvReader.setFieldSeparator(sheetConfig.getDataFileFieldSeparator());
        List<CsvRow> rows = csvReader.read(Paths.get(sheetConfig.getDataFileName()), Charset.forName(sheetConfig.getDataFileCharSet())).getRows();
        int rowNum = sheetConfig.getExcelStartRowNum();
        for (CsvRow rowData : rows) {
            SXSSFRow row = sheet.createRow(rowNum++);
            int colNum = sheetConfig.getExcelStartColNum();
            for (String col : rowData.getRawList()) {
                SXSSFCell cell = row.getCell(colNum, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                if (sheetConfig.getDataFileNumberTypeCols().contains(colNum+1)){
                    cell.setCellValue(Double.parseDouble(col.trim()));
                }else {
                    cell.setCellValue(col);
                }
                colNum++;
            }
        }
    }

    @Override
    public void run() {
        writeToExcel();
    }
}
